package com.yuqiaotech.dbpro.proxy;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Logger;

import javax.sql.DataSource;

import com.yuqiaotech.dbpro.filter.Filter;
import com.yuqiaotech.dbpro.filter.FilterChainImpl;

public class YQDataSource extends PropertiesProxyImpl implements DataSource{

	private DataSource dataSource;
		
	private List<Filter> filters = new ArrayList<Filter>();
	
	public YQDataSource(DataSource dataSource){
		this.dataSource = dataSource;
	}

	public Connection getConnection() throws SQLException {
		Connection conn;	
		if(getProxyFilters().size() == 0){
			conn = dataSource.getConnection();//获取c3p0连接池中的connection
		}else{
			conn = new FilterChainImpl(this).connection_connect();
		}
		return conn;
	}	
	
	
	public DataSource getRawDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}	
	
	public List<Filter> getProxyFilters() {
		return filters;
	}

	public void addFilter(Filter filter){
		this.filters.add(filter);
	}
	
	@Override
	public PrintWriter getLogWriter() throws SQLException {
		return dataSource.getLogWriter();
	}

	@Override
	public void setLogWriter(PrintWriter out) throws SQLException {
		dataSource.setLogWriter(out);
	}

	@Override
	public void setLoginTimeout(int seconds) throws SQLException {
		dataSource.setLoginTimeout(seconds);
	}

	@Override
	public int getLoginTimeout() throws SQLException {
		return dataSource.getLoginTimeout();
	}

	@Override
	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
		return dataSource.getParentLogger();
	}

	@Override
	public <T> T unwrap(Class<T> iface) throws SQLException {
		if(null == iface) {
			return null;
		}
		
		if(iface.isAssignableFrom(YQDataSource.class)) {
			return (T)this;
		}
		
		return super.unwrap(iface);
	}

	@Override
	public boolean isWrapperFor(Class<?> iface) throws SQLException {
		
		if(iface.isAssignableFrom(YQDataSource.class)) {
			return true;
		}
		return super.isWrapperFor(iface);
	}

	@Override
	public Connection getConnection(String username, String password)
			throws SQLException {
		return getConnection();
	}
	
	
	
    protected final AtomicLong connectionIdSeed  = new AtomicLong(10000);
    protected final AtomicLong statementIdSeed   = new AtomicLong(20000);
    protected final AtomicLong resultSetIdSeed   = new AtomicLong(50000);
    protected final AtomicLong transactionIdSeed = new AtomicLong(60000);
    protected final AtomicLong metaDataIdSeed    = new AtomicLong(80000);
    
    public long createConnectionId() {
        return connectionIdSeed.incrementAndGet();
    }

    public long createStatementId() {
        return statementIdSeed.getAndIncrement();
    }

    public long createMetaDataId() {
        return metaDataIdSeed.getAndIncrement();
    }

    public long createResultSetId() {
        return resultSetIdSeed.getAndIncrement();
    }

	public String getDbType() {
		// TODO Auto-generated method stub
		return null;
	}

	public List<Filter> getFilters() {
		return filters;
	}

	public void setFilters(List<Filter> filters) {
		this.filters = filters;
	}
}
